package myJs.projectCps.heatmapPlot

import com.softwaremill.quicklens._
import myJs.cps._
import myJs.tool.Tool._

import japgolly.scalajs.react.vdom.all._
import japgolly.scalajs.react._
import japgolly.scalajs.react.React.Fragment
import japgolly.scalajs.react.util.EffectCatsEffect._
import myJs.myPkg.Hooks._
import cats.effect._
import myJs.Implicits._

import scala.collection.immutable.SeqMap

/** Created by yz on 3/11/2020
 */
object LayoutCp {

  val plotO=Cp.plotO

  case class Props(
    basicData: plotO.LayoutData,
    basicDataChange: (plotO.LayoutData => plotO.LayoutData) => SyncIO[Unit]
  ){
    @inline def render: VdomElement = {
      Component(this)
    }
  }

  val Component = ScalaFnComponent[Props] { props =>

    val (varNameStr,setVarNameStr)=useState("")

    object FTool {

      def vChange[T](f: PathLazyModify[plotO.LayoutData, T])(g: String => T) = (v: String) => {
        props.basicDataChange {
          f.setTo(g(v))
        }
      }

      def strChange(f: PathLazyModify[plotO.LayoutData, String]) = FTool.vChange(f)(x=>x)

      def varNameStrChange=(v:String)=>{
        setVarNameStr(v)
      }

    }

    val showSampleMap = SeqMap("T" -> messages("yes"), "F" -> messages("no"))
    val basicData = props.basicData
    val clusterMethodMap = SeqMap(
      "complete" -> "complete",
      "single" -> "single",
      "ward.D" -> "ward",
      "average" -> "average",
      "mcquitty" -> "mcquitty"
    )
    val convMethodMap=SeqMap(
      "zScale" -> messages("zScale"),
      "log" -> messages("logTransform"),
      "none" -> messages("no"),
    )
    val normalMap=SeqMap(
      "col"->messages("byColumn"),
      "row"->messages("byRow"),
    )
    val logMap=SeqMap(
      "lg2"->"log2",
      "lg10"->"log10",
      "log"->messages("log"),
    )
    val hasBorderMap=SeqMap(
      "none"->messages("no"),
      "white"->messages("yes"),
    )

    Fragment(
      SelectInlineCp
        .Props(
          value = basicData.rowCluster,
          label = s"${messages("clusterRows")}",
          name = s"rowCluster",
          optionMap = showSampleMap,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.rowCluster)),
          labelWidth = 4,
          inputWidth = 8
        )
        .render,
      SelectInlineCp
        .Props(
          show = (basicData.rowCluster == "T"),
          name = "rowClusterMethod",
          value = basicData.rowClusterMethod,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.rowClusterMethod)),
          label = s"${messages("rowClusterMethod")}",
          inputWidth = 8,
          labelWidth = 4,
          optionMap = clusterMethodMap
        )
        .render,
      InputInlineCp
        .Props(
          show = (basicData.rowCluster == "T"),
          label = s"${messages("numberOfRowClusteringPartitions")}(1-${basicData.rowNum})",
          labelWidth = 4,
          inputWidth = 8,
          value = basicData.splitNum,
          name = "splitNum",
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.splitNum))
        )
        .render,
      SelectInlineCp
        .Props(
          value = basicData.colCluster,
          label = s"${messages("clusterColumns")}",
          name = s"colCluster",
          optionMap = showSampleMap,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.colCluster)),
          labelWidth = 4,
          inputWidth = 8
        )
        .render,
      SelectInlineCp
        .Props(
          show = (basicData.colCluster == "T"),
          name = "colClusterMethod",
          value = basicData.colClusterMethod,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.colClusterMethod)),
          label = s"${messages("columnClusterMethod")}",
          inputWidth = 8,
          labelWidth = 4,
          optionMap = clusterMethodMap
        )
        .render,
      InputInlineCp
        .Props(
          show = (basicData.colCluster == "T"),
          label = s"${messages("numberOfColumnClusteringPartitions")}(1-${basicData.colNum})",
          labelWidth = 4,
          inputWidth = 8,
          value = basicData.colSplitNum,
          name = "colSplitNum",
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.colSplitNum))
        )
        .render,
      SelectInlineCp
        .Props(
          name = "convMethod",
          value = basicData.convMethod,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.convMethod)),
          label = s"${messages("transform")}",
          inputWidth = 8,
          labelWidth = 4,
          optionMap = convMethodMap
        )
        .render,
      SelectInlineCp
        .Props(
          show=(basicData.convMethod=="zScale"),
          name = "normal",
          value = basicData.normal,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.normal)),
          label = s"${messages("zScale")}",
          inputWidth = 8,
          labelWidth = 4,
          optionMap = normalMap
        )
        .render,
      SelectInlineCp
        .Props(
          show=(basicData.convMethod=="log"),
          name = "log",
          value = basicData.log,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.log)),
          label = s"${messages("logTransform")}",
          inputWidth = 8,
          labelWidth = 4,
          optionMap = logMap
        )
        .render,
      SelectInlineCp
        .Props(
          name = "hasBorder",
          value = basicData.hasBorder,
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.hasBorder)),
          label = s"${messages("showCellBorder")}",
          inputWidth = 8,
          labelWidth = 4,
          optionMap = hasBorderMap,
          questionInfo = "若热图的尺寸较小，设定cell border参数后可能看不出来border，这是正常现象，需先把热图尺寸调合适了才能看到border。"
        )
        .render,
      BetweenInlineCp.Props(
        label = messages("picSizeWidthHeight"),
        startName = "width",
        start = basicData.width,
        startChange = FTool.strChange(modifyLens[plotO.LayoutData](_.width)),
        endName = "height",
        end = basicData.height,
        endChange = FTool.strChange(modifyLens[plotO.LayoutData](_.height))
      ).render,
      InputInlineCp
        .Props(
          show = (basicData.rowCluster == "T"),
          label = s"${messages("rowClusterTreeHeight")}",
          labelWidth = 4,
          inputWidth = 8,
          value = basicData.rowTreeHeight,
          name = "rowTreeHeight",
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.rowTreeHeight))
        )
        .render,
      InputInlineCp
        .Props(
          show = (basicData.colCluster == "T"),
          label = s"${messages("colClusterTreeHeight")}",
          labelWidth = 4,
          inputWidth = 8,
          value = basicData.colTreeHeight,
          name = "colTreeHeight",
          onChange = FTool.strChange(modifyLens[plotO.LayoutData](_.colTreeHeight))
        )
        .render
    )


  }

}
